﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ItalcoTransfer.italco.vo;
using System.Xml;
using ItalcoTransfer.XSD;

namespace ItalcoTransfer.Map
{
    public class Structure
    {
        public Structure()
        {
            Minimasters= new List<MinimasterVO>();
        }
        public static List<MinimasterVO> Minimasters = new List<MinimasterVO>();

        private void GetMinimasters(string sDirectorio)
        {
            string[] sFiles = System.IO.Directory.GetFiles(sDirectorio);
            Minimasters = new List<MinimasterVO>();
            foreach (string sFile in sFiles)
            {
                try
                {
                    XSD.Minimasters ds = new ItalcoTransfer.XSD.Minimasters();
                    ds.ReadXml(sFile);
                    foreach (XSD.Minimasters.MinimasterRow oRow in ds.Minimaster)
                    {
                        MinimasterVO master = new MinimasterVO();
                        master.Name = oRow.ID.Trim();
                        foreach (XSD.Minimasters.ValorRow vrow in ds.Valor)
                        {
                            if (!master.Valores.ContainsKey(vrow.ID.Trim()))
                                master.Valores.Add(vrow.ID.Trim(), vrow.Valor_Text.Trim());
                        }
                        if (Minimasters.Where(x => x.Name == master.Name).Count() == 0)
                            Minimasters.Add(master);
                    }
                    ds = null;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Se produjo el siguiente error en la carga del minimaster {0}: {1}", sFile, ex.Message);
                    //italco.utils.LogFile.LogERROR("Se produjo el siguiente error en la carga del minimaster {0}: {1}", sFile, ex.Message);
                }                
            }            
        }
        public void GetHyperfileStructure(ref List<HyperFileVO> estructura, string sFile,string DirectorioMinimasters)
        {
            //Obtenemos todos los minimasters disponibles.
            GetMinimasters(DirectorioMinimasters);
                        
            XSD.FILES ds = new ItalcoTransfer.XSD.FILES();
            ds.ReadXml(sFile);
            //Tenemos la estructura guardada en el dataset.
            foreach (FILES.FILERow filerow in ds.FILE)
            {
                //Creamos el objeto HyperFile
                HyperFileVO pFile = new HyperFileVO();
                pFile.Separador= filerow.caracter_Separador;
                //pFile.Email_aviso_ERROR = filerow.email_aviso_ERROR;
                //pFile.Email_aviso_OK= filerow.email_aviso_OK;
                pFile.Mascara_entrada= filerow.mascara_entrada;
                pFile.Mascara_salida= filerow.mascara_salida;
                pFile.Ruta_entrada= filerow.ruta_entrada;
                pFile.Ruta_salida= filerow.ruta_salida;
                pFile.Ruta_BackUps = filerow.ruta_backups;
                //pFile.Servidor_SMTP= filerow.servidor_SMTP;
                //pFile.Remitente_Email_aviso = filerow.remitente_email_aviso;
                //pFile.SMTP_User = filerow.SMTP_User;
                //pFile.SMTP_Password = filerow.SMTP_Password;
                //pFile.SMTP_Port = filerow.SMTP_Port;
                //pFile.RutaFicheroPeriodo = filerow.ruta_ficheroPeriodo;

                pFile.Utilizar_separador = filerow.utilizar_separador;
                //TODO: Mirar porque no carga este parametro
                pFile.Tipo_Fichero = filerow.tipo_fichero;
                EmployeeVO emp = new EmployeeVO();
                var fieldsInFile = (from fields in ds.FIELDS
                                     join field in ds.FIELD
                                         on fields.FIELDS_Id equals field.FIELDS_Id
                                     where fields.FILE_Id == filerow.FILE_Id
                                     select field);
                //En fieldsInFile tenemos la coleccion de campos que pertenecen a un File
                foreach (FILES.FIELDRow fRow in fieldsInFile)
                {
                    FieldVO fVO = new FieldVO();
                    if (emp.Fields.Where(x=> x.ID == fRow.ID).Count()>0)
                        fVO = emp.Fields.Where(x=> x.ID == fRow.ID ).Single();
                    fVO.ID = fRow.ID;
                    fVO.NombreSeccion = fRow.NOMBRE_SECCION;
                    fVO.GenerarAlta = fRow.GENERAR_ALTA;
                    fVO.GenerarBaja = fRow.GENERAR_BAJA;
                    fVO.GenerarModificacion = fRow.GENERAR_MODIFICACION;
                    fVO.ValidarNulo = fRow.VALIDAR_NULO;
                    fVO.NombreSeccion = fRow.NOMBRE_SECCION;
                    fVO.ValorDefecto = fRow.VALOR_POR_DEFECTO;
                    fVO.FormatoCampo = fRow.FORMATO_CAMPO;
                //    fVO.RegistroMultiple = fRow.CAMPO_MULTIPLE;
                    if (fRow.TIPO_VALOR == "P")
                    {
                        FieldPropertyVO fp = new FieldPropertyVO();
                        fp.NombrePropiedad = fRow.NOMBRE_PROPIEDAD;                        
                        fp.NumeroCampo = int.Parse(fRow.NUMERO_CAMPO);
                        //Las propiedades no pueden tener diccionarios si lo permitimos, podriamos 
                        //perder el diccionario del valor.
                        //if (!fRow.IsMINIMASTERNull() && fRow.MINIMASTER != "")
                        //{
                        //    if (Minimasters.Where(x => x.Name == fRow.MINIMASTER).Count() > 0)
                        //        fVO.Master = Minimasters.Where(x => x.Name == fRow.MINIMASTER).Single();
                        //}
                        //else
                        //    fVO.Master = null;
                        fVO.FieldProperties.Add(fp);
                        if (emp.Fields.Where(x=> x.ID == fRow.ID).Count()==0)
                            emp.AddField(fVO);
                    }
                    else
                    {                                              
                        if (!fRow.IsMINIMASTERNull() && fRow.MINIMASTER != "")
                        {
                            if (Minimasters.Where(x => x.Name == fRow.MINIMASTER).Count() > 0)
                                fVO.Master = Minimasters.Where(x => x.Name == fRow.MINIMASTER).Single();
                        }
                        else                                                    
                            fVO.Master = null;
                                             
                        fVO.NumeroCampo = int.Parse(fRow.NUMERO_CAMPO);
                        fVO.TamanyoMaximo = int.Parse(fRow.TAMANYO_MAXIMO);                                                
                        emp.AddField(fVO);
                    }                                        
                }
                pFile.AddEmployee(emp);
                estructura.Add(pFile);    
            }
            
        }

        public void FillFiles(List<HyperFileVO> estructura, ref List<HyperFileVO> resultado)
        {
            foreach (HyperFileVO file in estructura)
            {
                try
                {
                    string[] sFiles = System.IO.Directory.GetFiles(file.Ruta_entrada, file.Mascara_entrada);
                    foreach (string sFile in sFiles)
                    {
                        HyperFileVO fileout = new HyperFileVO();
                        fileout = file.Fill(sFile);
                        //if (fileout.HasErrors)
                        //{
                        //    if (fileout.Email_aviso_ERROR != "" && fileout.Servidor_SMTP != "")
                        //    {
                        //        //TODO: Enviar email de error
                        //    }
                        //}
                        //if (fileout.HasData)
                        resultado.Add(fileout);
                    }
                }
                catch (Exception ex)
                {
                    Console.Write("Se produjo el siguiente error al realizar FillFiles\n Ruta Entrada:{0} Mascara Entrada;{1} Error:{2}", file.Ruta_entrada, file.Mascara_entrada, ex.Message);
                    //italco.utils.LogFile.LogERROR("Se produjo el siguiente error al realizar FillFiles\n Ruta Entrada:{0} Mascara Entrada;{1} Error:{2}", file.Ruta_entrada, file.Mascara_entrada, ex.Message);
                }
            }
        }

               
    }
}
